// Context官方文档：https://zh-hans.reactjs.org/docs/context.html
import React, { createContext } from "react";

// 只有当组件所处的树中没有匹配到 Provider 时，其 defaultValue 参数才会生效。
const { Provider, Consumer } = createContext("defaultValue");

//组件结构：App-->SonA-->SonAsonB
//这里是将App的数据通过跨组件通信直接传给SonAsonB
const SonA = ({ msg }) => {
    return (
        <>
            <div>我是App的子组件SonA组件</div>
            <hr />
            <SonAsonB></SonAsonB>
            <SonAsonC></SonAsonC>
        </>
    );
};
const SonAsonB = () => {
    return (
        <div>
            我是SonA的子组件：SonAsonB
            <br />
            {/* 通过Consumer使用数据 */}
            {/* 在用到数据的地方使用（固定语法） */}
            {/* <Consumer>{(value) => ....}</Consumer> */}
            我接收到的数据：
            <Consumer>{(value) => <span>{value.msg}</span>}</Consumer>
        </div>
    );
};
const SonAsonC = () => {
    return (
        // 通过Consumer使用数据,直接将Consumer包到组件最外层，里面回调函数return出dom结构（固定语法）
        <Consumer>
            {(value) => {
                return (
                    <div>
                        我是SonA的子组件：SonAsonC
                        <br />
                        我接收到的数据：{value.name}
                        <button
                            onClick={() => value.changMag("我是修改过的值")}>
                            修改App传的message
                        </button>
                    </div>
                );
            }}
        </Consumer>
    );
};
//父组件App
class App extends React.Component {
    state = {
        message: "我是App组件的数据，我需要传到孙子组件SonAsonB或SonAsonC",
    };
    render() {
        return (
            // 使用Provider包裹根组件,value里为需要传的数据，value这个词不能更改
            // 一个 Provider 可以和多个消费组件有对应关系。多个 Provider 也可以嵌套使用，里层的会覆盖外层的数据。
            // 当 Provider 的 value 值发生变化时，它内部的所有消费组件都会重新渲染。
            <Provider
                value={{
                    msg: this.state.message,
                    name: "context",
                    changMag: (newText) => {
                        this.setState({
                            message: newText,
                        });
                    },
                }}>
                <div className='App'>
                    <SonA msg={this.state.message}></SonA>
                </div>
            </Provider>
        );
    }
}

export default App;
